#include "device.h"
#include "motor_dai_3opto.h"

#define MOTO_PWM_DUTY_START               50    //PWM_PERIOD_COUNT/2
#define MOTO_PWM_DUTY_MAX                 100   //PWM_PERIOD_COUNT
#define MOTO_PWM_PERIOD                   50    //PWM_PERIOD_COUNT  / PWM_COUNT_FREQ  = 50uS 
#define MOTO_PWM_DUTY_PERIOD              20000//20ms
#define MOTO_PWM_DUTY_PERIOD_COUNT        (MOTO_PWM_DUTY_PERIOD / MOTO_PWM_PERIOD)//占空比调节频率20ms            
#define MOTO_PWM_DUTY_INCREMENT           8

/* 电机状态 */
static enum
{
	MOTO_STA_STOP,                         //停止
	MOTO_STA_BRAKE,                        //刹车
	MOTO_STA_OPEN,                         //开门方向
	MOTO_STA_CLOSE,                        //关门方向
}MotorStatus = MOTO_STA_STOP;



static float pwm1_duty_cycle = 0;
static float pwm2_duty_cycle = 0;
extern LockNvData_stu_t lock_data;


static void Motor_PwmCb(VirtualHardware_enum_t dev, void *data, uint32_t len)
{
    static uint32_t count = 0;

    if (++count > MOTO_PWM_DUTY_PERIOD_COUNT)//400*50us = 20ms
    {
        count = 0;
        if((MOTO_STA_OPEN == MotorStatus && MOTO_DIR_CCW == lock_data.motor_direction) || (MOTO_STA_CLOSE == MotorStatus &&  MOTO_DIR_CW == lock_data.motor_direction))
        {
            if (pwm1_duty_cycle > 0 && pwm1_duty_cycle < MOTO_PWM_DUTY_MAX)
            {
                pwm1_duty_cycle += MOTO_PWM_DUTY_INCREMENT;
                if(pwm1_duty_cycle > MOTO_PWM_DUTY_MAX)
                {
                   pwm1_duty_cycle = MOTO_PWM_DUTY_MAX;
                }
                Device_SetPwm(vPWM_1, 20000, pwm1_duty_cycle);
            }
        }
        else if((MOTO_STA_OPEN == MotorStatus && MOTO_DIR_CW == lock_data.motor_direction) || (MOTO_STA_CLOSE == MotorStatus &&  MOTO_DIR_CCW == lock_data.motor_direction))
        {
            if (pwm2_duty_cycle > 0 && pwm2_duty_cycle < MOTO_PWM_DUTY_MAX)
            {
                pwm2_duty_cycle += MOTO_PWM_DUTY_INCREMENT;
                if(pwm2_duty_cycle > MOTO_PWM_DUTY_MAX)
                {
                    pwm2_duty_cycle = MOTO_PWM_DUTY_MAX;
                }
                Device_SetPwm(vPWM_2, 20000, pwm2_duty_cycle);
            }
        }
    }
}

void Motor_PwmInit(void)
{
    Device_RegisteredCB(vPWM_1, Motor_PwmCb);//注册PWM回调
}

//电机左转 上锁回拖/上锁回位、开锁方向 
void Motor_TurnLeft(void)
{
    MotorStatus = MOTO_STA_OPEN;
    if (lock_data.motor_direction == MOTO_DIR_CW)
    {
        pwm1_duty_cycle = 0;
        pwm2_duty_cycle = MOTO_PWM_DUTY_START;
    }
    else
    {
        pwm1_duty_cycle = MOTO_PWM_DUTY_START;
        pwm2_duty_cycle = 0;
    }
    //__OSAL_LOG("Motor_TurnLeft lock_data.motor_direction:%d\n",lock_data.motor_direction);
    Device_SetPwm(vPWM_1, 20000, pwm1_duty_cycle);
    Device_SetPwm(vPWM_2, 20000, pwm2_duty_cycle);
}

//电机右转 开锁回拖/开锁回位、关锁方向 
void Motor_TurnRight(void)
{
    MotorStatus = MOTO_STA_CLOSE;
    if (lock_data.motor_direction == MOTO_DIR_CW)
    {
        pwm1_duty_cycle = MOTO_PWM_DUTY_START;
        pwm2_duty_cycle = 0;
    }
    else
    {
        pwm1_duty_cycle = 0;
        pwm2_duty_cycle = MOTO_PWM_DUTY_START;
    }
    Device_SetPwm(vPWM_1, 20000, pwm1_duty_cycle);
    Device_SetPwm(vPWM_2, 20000, pwm2_duty_cycle);
}

//电机右转 开锁回拖/开锁回位、关锁方向 
void Motor_TurnRight_test(void)
{
    MotorStatus = MOTO_STA_CLOSE;
    if (lock_data.motor_direction == MOTO_DIR_CW)
    {
        pwm1_duty_cycle = 80;//90;//MOTO_PWM_DUTY_START; TODO:回拖待定
        pwm2_duty_cycle = 0;
    }
    else
    {
        pwm1_duty_cycle = 0;
        pwm2_duty_cycle = 80;//90;//MOTO_PWM_DUTY_START;
    }
    Device_SetPwm(vPWM_1, 20000, pwm1_duty_cycle);
    Device_SetPwm(vPWM_2, 20000, pwm2_duty_cycle);
}

//电机刹车
void Motor_Brake(void)
{
    MotorStatus = MOTO_STA_BRAKE;
    pwm1_duty_cycle = MOTO_PWM_DUTY_MAX;
    pwm2_duty_cycle = MOTO_PWM_DUTY_MAX;
    Device_SetPwm(vPWM_1, 20000, pwm1_duty_cycle);
    Device_SetPwm(vPWM_2, 20000, pwm2_duty_cycle);
}

//电机停止
void Motor_Stop(void)
{
    MotorStatus = MOTO_STA_STOP;
    pwm1_duty_cycle = 0;
    pwm2_duty_cycle = 0;
    Device_SetPwm(vPWM_1, 20000, pwm1_duty_cycle);
    Device_SetPwm(vPWM_2, 20000, pwm2_duty_cycle);
}

//改变电机方向（未校准状态下：开关锁堵转，需要调用该函数）
void Motor_ChangeDirection(void)
{
    lock_data.motor_direction = !lock_data.motor_direction;
}

//设置电机方向,0:逆时针上锁 1:顺时针上锁
//第一次上电时,若已是上锁状态则认为锁方向已经校准,此时需要设置电机方向,需要调用该函数
void Motor_SetDirection(uint8_t dir)
{
    lock_data.motor_direction = dir;
}

uint8_t Motor_GetDirection(void)
{
    uint8_t dir = 0XFF;
    OSAL_NvRead(OSAL_OFFSET(LockNvData_stu_t, motor_direction), (void *)&dir, sizeof(lock_data.motor_direction));
    //__OSAL_LOG("Motor_GetDirection dir:%d \n", dir);
    return dir;
}

//更新电机方向（未校准状态下：开关锁前，需要调用该函数）
void Motor_UpdateDirection(void)
{
    if(OSAL_NvRead(OSAL_OFFSET(LockNvData_stu_t, motor_direction), (void *)&lock_data.motor_direction, sizeof(lock_data.motor_direction)) != SUCCESS)//TODO 读取NV存储的电机方向
    {
        /*读取失败处理*/
        //__OSAL_LOG("ERR Motor_UpdateDirection lock_data.motor_direction:%d \n", lock_data.motor_direction);
    }
    else
    {
       //__OSAL_LOG("OK Motor_UpdateDirection lock_data.motor_direction:%d \n", lock_data.motor_direction);
    }
    if(lock_data.motor_direction != MOTO_DIR_CCW)
    {
        lock_data.motor_direction = MOTO_DIR_CW;
    }
}

//保存电机方向（未校准状态下：开关锁成功后，需要调用该函数）
void Motor_SaveDirection(void)
{
    if (OSAL_NvWrite(OSAL_OFFSET(LockNvData_stu_t, motor_direction), (void *)&lock_data.motor_direction, sizeof(lock_data.motor_direction))!= SUCCESS)
    {
        /*写入失败处理*/
        //__OSAL_LOG("ERR lock_data.motor_direction:%d \n", lock_data.motor_direction);
    }
    else
    {
        //__OSAL_LOG("OK lock_data.motor_direction:%d \n", lock_data.motor_direction);
    }
}

//设置关门时的电机方向
ErrorStatus Motor_LockMotorDirSet(uint8_t lock_motor_dir)
{
    if (OSAL_NvWrite(OSAL_OFFSET(LockNvData_stu_t, motor_direction), (void *)&lock_motor_dir, sizeof(lock_data.motor_direction))!= SUCCESS)
    {
        /*写入失败处理*/
		return ERROR;
    } 
	return SUCCESS;
}
